package com.example.demo.service.impl;

import com.example.demo.dao.TbBlogDao;
import com.example.demo.dao.TbMessageForBlogDao;
import com.example.demo.entity.TbBlogEntity;
import com.example.demo.entity.TbMessageForBlogEntity;
import com.example.demo.entity.response.BlogEntity;
import com.example.demo.service.TbBlogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.persistence.Id;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class TbBlogServiceImpl implements TbBlogService {

    TbBlogDao blogDao;
    TbMessageForBlogDao messageForBlogDao;

    @Autowired
    public void setBlogDao(TbBlogDao blogDao) {
        this.blogDao = blogDao;
    }
    @Autowired
    public void setMessageForBlogDao(TbMessageForBlogDao messageForBlogDao) {
        this.messageForBlogDao = messageForBlogDao;
    }

    @Override
    public boolean pushBlog(String title, String content, String [] tagNames) {
        TbBlogEntity blogEntity = new TbBlogEntity();
        String tagNameJoin = "";
        for (String tagName : tagNames) {
            tagNameJoin += "," + tagName;
        }
        if(tagNameJoin.startsWith(",") && tagNameJoin.length() > 1) {
            tagNameJoin = tagNameJoin.substring(1);
        }
        blogEntity.setTagName(tagNameJoin);
        blogEntity.setBlogTitle(title);
        blogEntity.setBlogContent(content);
        blogEntity.setBlogUp(0);
        blogEntity.setBlogViewnum(0);
        blogEntity.setBlogDatetime(new Timestamp(System.currentTimeMillis()));
        blogDao.save(blogEntity);
        return true;
    }

    public Map<String, Object> getBlogsByPage(int index, int size) {
        Sort sort = Sort.by(Sort.Order.desc("blogDatetime"));
        Map<String, Object> result = new HashMap<>();
        if(index <= 0) {
            index = 1;
        }
        if(size <= 0) {
            size = 10;
        }
        Pageable pageable = PageRequest.of(index - 1, size, sort);
        Page<TbBlogEntity> blogPage = blogDao.findAll(pageable);
        // 总数
        long total = blogPage.getTotalElements();
        List<TbBlogEntity> blogEntities = blogPage.getContent();
        List<BlogEntity> responseEntityList = new ArrayList<>();
        for (TbBlogEntity blog : blogEntities) {
            int blogId = blog.getBlogId();
            int count = messageForBlogDao.countByBlogId(blogId);
            BlogEntity responseEntity = new BlogEntity();
            responseEntity = copy(blog, responseEntity);
            responseEntity.setRemarkNum(count);
            responseEntityList.add(responseEntity);
        }
        result.put("content", responseEntityList);
        result.put("total", total);
        return result;
    }

    public void deleteBlogById(int [] ids) {
        for (int id : ids) {
            blogDao.deleteById(id);
        }
    }

    public void updateBlogById(int id, boolean changeContent, String text) {
        TbBlogEntity blogEntity = blogDao.getOne(id);
        if(blogEntity == null) return;
        if(changeContent) {
            blogEntity.setBlogContent(text);
        } else {
            blogEntity.setBlogTitle(text);
        }
        blogEntity.setBlogDatetime(new Timestamp(System.currentTimeMillis()));
        blogDao.save(blogEntity);
    }

    public Map<String, Object> getBlogsByTagName(String tagName, Integer index, Integer size) {

        Sort sort = Sort.by(Sort.Order.desc("blogDatetime"));
        Map<String, Object> result = new HashMap<>();
        if(index <= 0) {
            index = 1;
        }
        if(size <= 0) {
            size = 10;
        }
        Pageable pageable = PageRequest.of(index - 1, size, sort);
        Page<TbBlogEntity> blogEntitiesPage = blogDao.findByTagNameLike(tagName, pageable);
        List<TbBlogEntity> blogList = blogEntitiesPage.getContent();
        long total = blogEntitiesPage.getTotalElements();
        List<BlogEntity> responseEntityList = new ArrayList<>();
        for (TbBlogEntity blog : blogList) {
            int blogId = blog.getBlogId();
            int count = messageForBlogDao.countByBlogId(blogId);
            BlogEntity responseEntity = new BlogEntity();
            responseEntity = copy(blog, responseEntity);
            responseEntity.setRemarkNum(count);
            responseEntityList.add(responseEntity);
        }
        result.put("content", responseEntityList);
        result.put("total", total);
        return result;
    }

    public Map<String, Object> getBlogMessageById(Integer id, Integer index, Integer size) {
        if(index <= 0) {
            index = 1;
        }
        if(size <= 0) {
            size = 10;
        }
        Sort sort = Sort.by(Sort.Order.desc("messageForBlogDatetime"));
        Pageable pageable = PageRequest.of(index - 1, size, sort);
        Page<TbMessageForBlogEntity> messagePage = messageForBlogDao.findByBlogId(id, pageable);
        Map<String, Object> result = new HashMap<>();
        result.put("content", messagePage.getContent());
        result.put("total", messagePage.getTotalElements());
        return result;
    }

    public void deleteMessageForBlogById(Integer id) {
        messageForBlogDao.deleteById(id);
    }

    public void like(Integer id) {
        TbBlogEntity blogEntity = blogDao.getOne(id);
        if(blogEntity != null) {
            int blogUp = blogEntity.getBlogUp();
            blogUp += 1;
            blogEntity.setBlogUp(blogUp);
            blogDao.save(blogEntity);
        }
    }

    public Map<String, Object> getBlogByLike(String value, Integer index, Integer size) {
        if(index <= 0) {
            index = 1;
        }
        if(size <= 0) {
            size = 10;
        }
        Sort sort = Sort.by(Sort.Order.desc("blogDatetime"));
        Pageable pageable = PageRequest.of(index - 1, size, sort);
        Page<TbBlogEntity> tbBlogPage = blogDao.findByBlogTitleContainingOrBlogContentContaining(value, value, pageable);
        List<TbBlogEntity> tbBlogList = tbBlogPage.getContent();
        long total = tbBlogPage.getTotalElements();
        List<BlogEntity> responseEntityList = new ArrayList<>();
        for (TbBlogEntity blog : tbBlogList) {
            int blogId = blog.getBlogId();
            int count = messageForBlogDao.countByBlogId(blogId);
            BlogEntity responseEntity = new BlogEntity();
            responseEntity = copy(blog, responseEntity);
            responseEntity.setRemarkNum(count);
            responseEntityList.add(responseEntity);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("content", responseEntityList);
        result.put("total", total);
        return result;
    }

    public List<TbBlogEntity> getBlogByLikeId(Integer id) {
        return blogDao.findByBlogIdContaining(id + "");
    }

    /**
     * 深拷贝对象属性
     * @param source 来源
     * @param destination 目的地
     * @return 目的地
     */
    private BlogEntity copy(TbBlogEntity source, BlogEntity destination) {
        destination.setBlogContent(source.getBlogContent());
        destination.setBlogDatetime(source.getBlogDatetime());
        destination.setBlogId(source.getBlogId());
        destination.setBlogTitle(source.getBlogTitle());
        destination.setBlogUp(source.getBlogUp());
        destination.setBlogViewnum(source.getBlogViewnum());
        destination.setTagName(source.getTagName());
        return destination;
    }
}
